--[[
 -- *名称:PairStraightTypeAnalyzer
 -- *描述:连对
 -- *版权:Copyright © 2016-2018 深圳市三只小熊科技有限公司 版权所有
 -- *作者:Administrator
 -- *创建日期:2017-11-10
 -- *修改日期:2017-11-10
 ]]
local DdzSuitAnalyzer = require(basePath.."suit/ddzsuitanalyzer");
local PairStraightTypeAnalyzer = pokercore.class(DdzSuitAnalyzer,false);
local Cards = require(basePath .. "domain/cards");
local LIMIT_SIZE = 6;
local TUPLE_SIZE = 2;
PairStraightTypeAnalyzer.LIMIT_SIZE = 6 ;
PairStraightTypeAnalyzer.TUPLE_SIZE = 2 ;

function PairStraightTypeAnalyzer:getSuitType()
	return DdzCardTypes.PAIR_STRAIGHT;
end


--@Override
function PairStraightTypeAnalyzer:doCheckRule( cards, term, result )
	if (result:getCardNum() >= LIMIT_SIZE 
				and result:getCardNum() % TUPLE_SIZE == 0) then --// 三顺至少六张且数量为三的倍数
		if (result:isAllCardLazi()) then --// 都是癞子
			--print("PairStraightTypeAnalyzer:doCheckRule 1 都是癞子")
			return false;
	    else 
			if (result:getNoneLaziValueCounter():hasJoker()) then -- // 非赖部分有王
				--print("PairStraightTypeAnalyzer:doCheckRule 2 非赖部分有王")
				return false;
			end
			if (result:getNoneLaziValueCounter():getValueCount(PokerGameConstant.NUMBER_2_VALUE) > 0) then -- // 非赖部分有2
				--print("PairStraightTypeAnalyzer:doCheckRule 3 非赖部分有2")
				return false;
			end
			local allNumber = result:getNoneLaziValueCounter():getAllValues();
			for _, number in ipairs(allNumber) do -- // 全是单张，对子，三张
				if (result:getNoneLaziValueCounter():getValueCount(number) > TUPLE_SIZE) then
					--print("PairStraightTypeAnalyzer:doCheckRule 4 全是单张，对子，三张")
					return false;
				end
			end
			local tupleNum =  math.floor(result:getCardNum() / TUPLE_SIZE); --// 分析有几组牌，三顺中一对算做一组
			--// 遍历寻找所有可能的顺子
			for valueTemp = PokerGameConstant.NUMBER_2_VALUE - 1 -- 从A开始
					, PokerGameConstant.NUMBER_3_VALUE + (tupleNum - 1), -1 do
				if (DdzTypeUtil.ensureStaight(valueTemp,TUPLE_SIZE,TUPLE_SIZE, cards, term, result)) then
					return true;
				end
			end
			--print("PairStraightTypeAnalyzer:doCheckRule 5")
			return false;
		 end
	else 
		 --print("PairStraightTypeAnalyzer:doCheckRule 6")
	 return false;
	end
end

--@Override
function PairStraightTypeAnalyzer:doAnalysizeLaizi(cards,term,onlyMaxValue)
	local cardsResult = {}
	local result = cards:getResult();
	local laiziCardList = cards:subList(result:getCardNum() - result:getLaziCardNum()+1, result:getCardNum());
	local tupleNum = math.floor(result:getCardNum() / TUPLE_SIZE); -- // 分析有几组牌，顺子中单张也算做一组
	--// 遍历寻找所有可能的顺子
	for beginValueTemp = PokerGameConstant.NUMBER_2_VALUE - 1 -- // 从A开始
			, PokerGameConstant.NUMBER_3_VALUE + tupleNum - 1, -1 do
		if (DdzTypeUtil.ensureStaight(beginValueTemp,TUPLE_SIZE,TUPLE_SIZE, cards, term, result)) then
			local laiziCardIndex = 0;
			for  valueTemp = beginValueTemp,  beginValueTemp - tupleNum +1, -1 do --// 从大到小
				local valueTempNum = result:getNoneLaziValueCounter():getValueCount(valueTemp);
				local needLaiziCardNum = TUPLE_SIZE - valueTempNum;
				for  i = 1, needLaiziCardNum do
					laiziCardIndex = laiziCardIndex + 1;
					laiziCardList[laiziCardIndex]:changeCard(valueTemp);
					--print("#############valueTempNum ->",valueTempNum) ;
					
				end
				
			end
			local cardsCopy = cards:clone();
			self:analysize(cardsCopy, term);
			table.insert(cardsResult,cardsCopy:clone());
			if (onlyMaxValue) then
				break; -- // 取完最大一组就跳出
			end
		end
	end
	return cardsResult;
end

--@Override
function  PairStraightTypeAnalyzer:containsPossibleCards(handCards,term) 
	local result = handCards:getResult();
	if (result:getCardNum() - result:getJokerCardNum() < LIMIT_SIZE) then --// 张数不够
		return false;
	end
	--// 遍历寻找所有可能的顺子
	for beginValueTemp = PokerGameConstant.NUMBER_2_VALUE - 1 --// 从A开始
			,PokerGameConstant.NUMBER_3_VALUE + LIMIT_SIZE / TUPLE_SIZE - 1,-1 do
		if (DdzTypeUtil.ensureTupleStaightDesc(
				beginValueTemp, LIMIT_SIZE / TUPLE_SIZE, TUPLE_SIZE, handCards, term, result)) then--// 最低标准顺一下
			return true;
		end
	end
	return false;
end
	
--/** 最多使用癞子的数量 */
local MAX_USE_LAIZI_CARD_NUM = 8;

--** 防重复判定的比例值 参照 int key = tupleNum * TUPLE_WEIGHT + beginValueTemp; */
local TUPLE_WEIGHT = 1000000;

--/** 癞子权重，区分癞子变成的5 和 原本就是5 */
local LAIZI_WEIGHT = 1000;
	
--@Override
function PairStraightTypeAnalyzer:doListPossibleCards(handCards,term)
	local cardsResult = {};
	--// 非癞子部分
	local result = handCards:getResult();
	local noneLaiziCardList = handCards:subList(1, result:getNoneCardNum());
	local noneLaiziCards = DdzTypeUtil.createCardsCopy(noneLaiziCardList);
	noneLaiziCards:setResult(handCards:getResult():clone());
	--// 癞子部分
 	local laiziCardList = handCards:subList(result:getNoneCardNum()+1, result:getCardNum());
	local laiziCards = DdzTypeUtil.createCardsCopy(laiziCardList);
	laiziCards:setResult(handCards:getResult():clone());

	local laiziCardNum = result:getLaziCardNum();
	local maxUseLaiziCardNum = MAX_USE_LAIZI_CARD_NUM < laiziCardNum and MAX_USE_LAIZI_CARD_NUM or laiziCardNum;
	local exsitKeys = {};
	for useLaiziCardNum = 0,maxUseLaiziCardNum do
		local useLaiziCardList = DdzTypeUtil.cloneSublistedCards(laiziCards, 1, useLaiziCardNum); --// 补癞子
		table.reverse(useLaiziCardList); --// 因为这里是倒序赋值，避免 把点数小的癞子牌赋成大值又把点数大的癞子牌赋成小值 的疑惑
		local modelCards = DdzTypeUtil.cloneCardsAndAddCardList(noneLaiziCards, useLaiziCardList);-- // 常规牌补上癞子
		local modelResult = modelCards:getResult();
		modelResult:collectNumber(modelCards, term); --// 重新获取下点值
		--// 从5顺开始找 10.JQK1 找完找 9.10.J.Q.K.1 在找 8.9.10.J.Q.K.1 
		for tupleNum = LIMIT_SIZE / TUPLE_SIZE, modelResult:getCardNum() / TUPLE_SIZE do
			local partLenResult = {} --// 部分长度的结果 
			--// 遍历寻找所有可能的顺子  10.J.Q.K.1 找完找 9.10.J.Q.K 在找 8.9.10.J.Q
			for beginValueTemp = PokerGameConstant.NUMBER_2_VALUE - 1 --// 从A开始
					, PokerGameConstant.NUMBER_3_VALUE + tupleNum - 1,-1 do
				local laiziCardIndex = 0;
				local straightKey = tupleNum * TUPLE_WEIGHT + beginValueTemp;
				if (not exsitKeys[straightKey] --// 每种顺子仅判定一次
						and DdzTypeUtil.ensureTupleStaightDesc(beginValueTemp, tupleNum, TUPLE_SIZE, modelCards, term, modelResult)) then
					exsitKeys[straightKey] = true;
					local straightCards = pokercore.new(Cards);
					for valueTemp = beginValueTemp,beginValueTemp - tupleNum+1,-1 do -- // 从大到小
						local valueTempNum = modelResult:getNoneLaziValueCounter():getValueCount(valueTemp);
						if (valueTempNum >= TUPLE_SIZE) then
							straightCards:addCards(DdzTypeUtil.cloneObtainedCards(modelCards, valueTemp, TUPLE_SIZE));
						else 
							straightCards:addCards(DdzTypeUtil.cloneObtainedCards(modelCards, valueTemp, valueTempNum));
							local needLaiziCardNum = TUPLE_SIZE - valueTempNum;
							for  i = 1, needLaiziCardNum do --// 用了癞子才加上，不会任意补全（癞子不会去替代玩家已有的顺子中的元素）
								laiziCardIndex = laiziCardIndex + 1 ;
								local laiziCardCopy = useLaiziCardList[laiziCardIndex]:clone();
								laiziCardCopy:changeCard(valueTemp);
								straightCards:addCard(laiziCardCopy);
							end
						end
					end
					local laiziNumKey = 0;
					for _,card in ipairs(straightCards:getCardList()) do
						if card:isLazi() then -- // 癞子权重，区分癞子变成的5 和 原本就是5
							laiziNumKey = laiziNumKey + LAIZI_WEIGHT + card:getValue();
						else 
							laiziNumKey = laiziNumKey + card:getValue();
						end
					end
					if (not exsitKeys[laiziNumKey] -- // 保证癞子不会变形 比如  **10** 和 10**** 只出现一次最大的提牌
							and self:match(straightCards, term)) then
						exsitKeys[laiziNumKey] = true ;
						self:analysize(straightCards, term);
						table.insert(partLenResult,1,straightCards); --// 这里倒序加入，保证从小到大
					    
					end
				end
			end
			table.addAll(cardsResult,partLenResult);
		end
	end
	return cardsResult;
end


return PairStraightTypeAnalyzer;

